<script setup lang="ts">
import { ref, onMounted } from 'vue'
import type { FormInst, FormItemInst, FormItemRule, FormRules, } from 'naive-ui'
import { NButton, NModal, NPageHeader, NDivider, NImage, NInput, NForm, NFormItem, NIcon, NPopconfirm } from 'naive-ui'
import SvgIcon from './SvgIcon.vue';
import { useMessage } from 'naive-ui'
import { useRouter } from 'vue-router';
import { encrypt, getJmg } from '@/service/jmg';
import { storeToRefs } from 'pinia';
import { useCounterStore } from '@/stores/counter';
import { UPDATE_USER_INFO } from '@/service/apis/apis';
const counterStore = useCounterStore()
const { info } = storeToRefs(counterStore)
const router = useRouter()
const secret = ref('')
const model = ref<any>({})

onMounted(() => {
    getJmg((reslut: any) => {
        if (reslut.error) {
            message.error("本地加密狗检测失败！")
            router.go(-1)
        } else {
            secret.value = reslut.secret
        }
    })
    model.value = {
        face_data: 'data:image/*;base64,' + info.value.人脸数据,
        phone: info.value.手机号,
        isWxBind: info.value.是否绑定微信,
        oldPassword: null,
        password: null,
        reenteredPassword: null
    }
    console.log('基础设置', info.value)
})
const phoneFormRef = ref<FormInst | null>(null)
const passwordFormRef = ref<FormInst | null>(null)
const rPasswordFormItemRef = ref<FormItemInst | null>(null)
const message = useMessage()

function validatePasswordStartWith(
    rule: FormItemRule,
    value: string
): boolean {
    return (
        !!model.value.password
        && model.value.password.startsWith(value)
        && model.value.password.length >= value.length
    )
}
function validatePasswordSame(rule: FormItemRule, value: string): boolean {
    return value === model.value.password
}
function validatePhoneFormat() {
    // 正则 '11位 必须数字'
    const regex = /^[0-9]{11}$/;
    return regex.test(model.value.phone);
}
function validatePasswordContent() {
    const { password } = model.value
    // 正则 '至少8位 必须含有大小写字母和数字'
    const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{8,}$/;
    return regex.test(password);
}
const rules: FormRules = {
    face_data: [
        {
            required: false,
            message: '请设置扫脸照片'
        }
    ],
    phone: [
        // {
        //     required: true,
        //     message: '请输入手机号',
        //     trigger: ['input', 'blur']
        // },
        {
            validator: validatePhoneFormat,
            message: '手机号格式不正确',
            trigger: ['input', 'blur']
        },
    ],
    oldPassword: [
        {
            required: true,
            message: '请输入旧密码',
            trigger: ['input', 'blur']
        },
    ],
    password: [
        {
            required: true,
            message: '请输新入密码'
        },
        {
            validator: validatePasswordContent,
            message: '至少8位 必须含有大小写字母和数字',
            trigger: ['input', 'blur']
        },
    ],
    reenteredPassword: [
        {
            required: true,
            message: '请再次输入密码',
            trigger: ['input', 'blur']
        },
        {
            validator: validatePasswordStartWith,
            message: '两次密码输入不一致',
            trigger: 'input'
        },
        {
            validator: validatePasswordSame,
            message: '两次密码输入不一致',
            trigger: ['blur', 'password-input']
        }
    ]
}

const videoRef = ref()
const streams = ref()
const myConstraints = ref({
    video: {
        facingMode: "user", // 优先调用前置摄像头
    },
})

const videoOpen = () => {
    showModal.value = true
    navigator.mediaDevices.getUserMedia(myConstraints.value).then(
        (stream) => {
            streams.value = stream
            videoRef.value.srcObject = stream;
            //播放视频
            videoRef.value.play();
        },
        (error) => {
            console.error(error.name || error);
        }
    );
};
const videoClose = () => {
    if (streams.value) {
        streams.value.getTracks().forEach((track: any) => track.stop());
    }
};
const handleShoot = () => {
    console.log('shoot', videoRef)
    let canvas = document.createElement("canvas");
    canvas.width = 600 * 0.9; // 不知道为什么有拉伸，所以乘以0.9
    canvas.height = 400;
    const context = canvas.getContext("2d");
    context?.drawImage(videoRef.value, 0, 0, canvas.width, canvas.height);
    handleChangeFaceData(canvas.toDataURL("image/png", 0.1))
    showModal.value = false
    videoClose()
}

const changingPhone = ref(false)
const changingPassword = ref(false)
const showModal = ref(false)
function handlePasswordInput() {
    if (model.value.reenteredPassword) {
        rPasswordFormItemRef.value?.validate({ trigger: 'password-input' })
    }
}
/**
 * 提交修改
 * handleChangePhone 改手机号
 * handleChangePassword 改密码
 * handleUnBindWx 解绑微信
 * handleChangeFaceData 改人脸数据
 */
function handleSubmit(submitObj: any, cb?: Function) {
    UPDATE_USER_INFO({ params: JSON.stringify(submitObj) }).then((res: any) => {
        if (res.stacode === 200) {
            message.success('修改成功')
            cb!()
        } else {
            message.error(res.msg || '修改失败')
        }
    })
}
function handleChangePhone() {
    phoneFormRef.value?.validate((errors: any) => {
        if (!errors) {
            console.log('更新手机号', model.value.phone)
            handleSubmit({ phone: model.value.phone }, () => changingPhone.value = false)
        }
    })
}
function handleChangePassword() {
    passwordFormRef.value?.validate((errors: any) => {
        if (!errors) {
            console.log('更新密码', model.value)
            handleSubmit({
                password_old: encrypt(model.value.oldPassword, secret.value),
                password_new: encrypt(model.value.password, secret.value)
            }, () => {
                model.value.oldPassword = ''
                model.value.password = ''
                model.value.reenteredPassword = ''
                changingPassword.value = false
                window.location.href = '/login'
            })
        }
    })
}
function handleUnBindWx() {
    handleSubmit({ unbindwx: true }, () => model.value.isWxBind = false)
}
function handleChangeFaceData(faceData: string) {
    handleSubmit({ face_data: faceData }, () => model.value.face_data = faceData)
}
</script>
<template>
    <div style="margin-bottom: 30px;">
        <n-page-header title="基础设置" />
    </div>
    <n-modal v-model:show="showModal" preset="card" style="width: 600px" title="拍一张脸部照片" v-on:close="videoClose">
        <div class="rl_video">
            <div class="rl_video_ladding">
                <img src="../assets/image/face_frame.png" class="face_img"></img>
                <video ref="videoRef" class="rl_video_ladding_video"></video>
            </div>
        </div>
        <n-button type="primary" attr-type="button" @click="handleShoot">拍照</n-button>
    </n-modal>
    <div style="text-align: left;">
        <div class="settingItemTitle">手机号</div>
        <div class="settingContentShow">
            <span v-if="!changingPhone" class="settingContentText">{{ model.phone }}</span>
            <n-form v-else ref="phoneFormRef" :model="model" :rules="rules" style="width: 380px;">
                <n-form-item path="phone" label="新手机号:">
                    <n-input v-model:value="model.phone" placeholder="输入新手机号" maxlength="11" show-count />
                </n-form-item>
                <n-button size="small" type="primary" class="settingContentButton"
                    @click="handleChangePhone">修改</n-button>
            </n-form>
            <n-button v-if="!changingPhone" text type="primary" class="settingContentButton"
                @click="changingPhone = true">修改</n-button>
            <n-button v-else text type="primary" class="settingContentButton"
                @click="changingPhone = false">取消</n-button>
        </div>
        <n-divider />
        <div class="settingItemTitle">密码</div>
        <div class="settingContentShow">
            <span v-if="!changingPassword" class="settingContentText">已设置</span>
            <n-form v-else ref="passwordFormRef" :model="model" :rules="rules" style="width: 380px;">
                <n-form-item path="oldPassword" label="旧密码:">
                    <n-input v-model:value="model.oldPassword" type="password" placeholder="输入旧密码" maxlength="16"
                        show-count />
                </n-form-item>
                <n-form-item path="password" label="新密码:">
                    <n-input v-model:value="model.password" type="password" @input="handlePasswordInput"
                        placeholder="输入新密码(至少8位 必须含有大小写字母和数字)" maxlength="16" show-count />
                </n-form-item>
                <n-form-item first path="reenteredPassword" label="重复新密码:">
                    <n-input v-model:value="model.reenteredPassword" :disabled="!model.password" type="password"
                        placeholder="再次输入新密码" maxlength="16" show-count />
                </n-form-item>
                <n-button size="small" type="primary" class="settingContentButton"
                    @click="handleChangePassword">修改</n-button>
            </n-form>
            <n-button v-if="!changingPassword" text type="primary" class="settingContentButton"
                @click="changingPassword = true">修改</n-button>
            <n-button v-else text type="primary" class="settingContentButton"
                @click="changingPassword = false">取消</n-button>
        </div>
        <n-divider />
        <div class="settingItemTitle">微信号</div>
        <div class="settingContentShow">
            <span class="settingContentText">{{ model.isWxBind ? '已绑定' : '未绑定微信（请前往登录界面，通过微信扫码登录绑定）' }}</span>
            <n-popconfirm v-if="model.isWxBind" @positive-click="handleUnBindWx" positive-text="确定"
                :negative-text="null">
                <template #trigger>
                    <n-button text type="primary" class="settingContentButton">解绑</n-button>
                </template>
                确定解绑？
            </n-popconfirm>
        </div>
        <n-divider />
        <div class="settingItemTitle">人脸信息</div>
        <div class="settingContentShow">
            <div v-if="model.face_data" style="display: flex; align-items: center;">
                <n-image width="75" :src="model.face_data" />
                <n-popconfirm @positive-click="handleChangeFaceData('')" positive-text="确定" :negative-text="null">
                    <template #trigger>
                        <n-button v-if="model.face_data" size="large" text style="margin-left: 15px;">
                            <n-icon>
                                <SvgIcon iconClass="guanbi1"></SvgIcon>
                            </n-icon>
                        </n-button>
                    </template>
                    确定删除？
                </n-popconfirm>
            </div>
            <n-button v-if="model.face_data" text type="primary" class="settingContentButton"
                @click="videoOpen">重新录入</n-button>
            <n-button v-else text type="primary" class="settingContentButton" @click="videoOpen">录入人脸信息</n-button>
        </div>
    </div>
</template>
<style scoped>
.settingItemTitle {
    font-size: 15px;
    font-weight: 600;
    margin-top: 5px;
    margin-bottom: 10px;
}

.settingContentShow {
    display: flex;
    justify-content: space-between;
}

.settingContentText {
    font-size: 14px;
    color: gray;
}

.settingContentButton {
    font-size: 14px;
}

.rl_video {
    /* width: 400px; */
    height: 270px;
    border-radius: 50%;
    /*background-color: rgb(38, 57, 57);*/
    position: relative;
}

.rl_video_ladding {
    width: 260px;
    height: 260px;
    border-radius: 50%;
    background-color: rgb(38, 57, 57);
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    background: white;
    animation: changeBg 5s infinite;
    position: relative;
}

.rl_video_ladding_video {
    width: 250px;
    height: 250px;
    border-radius: 50%;
    object-fit: cover;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);

}

.face_img {
    width: 250px;
    height: 250px;
    border-radius: 50%;
    left: 2%;
    top: 2%;
    position: absolute;
    z-index: 100;
}
</style>